package cn.anzhiyublog.staranimegallery.controller;

import cn.anzhiyublog.staranimegallery.annotation.Auth;
import cn.anzhiyublog.staranimegallery.model.domain.Picture;
import cn.anzhiyublog.staranimegallery.model.domain.Tag;
import cn.anzhiyublog.staranimegallery.model.dto.picture.*;
import cn.anzhiyublog.staranimegallery.model.enums.Authority;
import cn.anzhiyublog.staranimegallery.model.enums.StatusCode;
import cn.anzhiyublog.staranimegallery.model.response.Response;
import cn.anzhiyublog.staranimegallery.model.vo.PictureVO;
import cn.anzhiyublog.staranimegallery.service.PictureService;
import cn.anzhiyublog.staranimegallery.service.TagService;
import cn.anzhiyublog.staranimegallery.service.UserService;
import cn.anzhiyublog.staranimegallery.util.ResultUtils;
import cn.anzhiyublog.staranimegallery.util.ThrowUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 图片控制层
 *
 * @author 安知一只鱼
 */
@RestController
@RequestMapping("/picture")
public class PictureController {
    @Autowired
    private PictureService pictureService;
    @Autowired
    private UserService userService;
    @Autowired
    private TagService tagService;

    /**
     * 图片文件上传
     *
     * @param multipartFile 图片文件
     * @param pictureUploadRequest 图片上传请求
     * @param httpServletRequest HTTP请求头信息
     * @return 图片封装信息
     */
    @Auth(value = {Authority.MANAGE,Authority.GENERAL})
    @PostMapping("/upload/file")
    public Response<PictureVO> uploadPictureByFile(@RequestPart("file")MultipartFile multipartFile,
                                                   PictureUploadRequest pictureUploadRequest,
                                                   HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(pictureUploadRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        Picture picture = pictureService.uploadPictureByFile(multipartFile, pictureUploadRequest, userService.getLoginUser(httpServletRequest));
        // 数据脱敏
        PictureVO pictureVO = pictureService.ObjToVO(picture);
        return ResultUtils.success(pictureVO);

    }

    /**
     * 图片URL上传
     *
     * @param pictureUrlUploadRequest 图片URL上传请求
     * @param httpServletRequest HTTP请求头信息
     * @return 图片封装信息
     */
    @Auth(value = {Authority.MANAGE,Authority.GENERAL})
    @PostMapping("/upload/url")
    public Response<PictureVO> uploadPictureByUrl(@RequestBody PictureUrlUploadRequest pictureUrlUploadRequest,
                                                  HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(pictureUrlUploadRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        Picture picture = pictureService.uploadPictureByUrl(pictureUrlUploadRequest, userService.getLoginUser(httpServletRequest));
        // 数据脱敏
        PictureVO pictureVO = pictureService.ObjToVO(picture);
        return ResultUtils.success(pictureVO);
    }

    /**
     * 图片爬虫上传
     *
     * @param pictureSpiderUploadRequest 图片爬虫上传请求
     * @param httpServletRequest HTTP请求头信息
     * @return 成功次数
     */
    @Auth(value = Authority.MANAGE)
    @PostMapping("/upload/spider")
    public Response<PictureSpiderUploadResult> uploadPictureBySpider(@RequestBody PictureSpiderUploadRequest pictureSpiderUploadRequest,
                                                    HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(pictureSpiderUploadRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        PictureSpiderUploadResult result = pictureService.uploadPictureBySpider(pictureSpiderUploadRequest, userService.getLoginUser(httpServletRequest));
        return ResultUtils.success(result);
    }

    /**
     * 删除图片
     *
     * @param pictureDeleteRequest 图片删除请求
     * @param httpServletRequest HTTP请求头信息
     * @return 删除成功
     */
    @Auth(value = {Authority.MANAGE,Authority.GENERAL})
    @PostMapping("/delete")
    public Response<?> deletePicture(@RequestBody PictureDeleteRequest pictureDeleteRequest,
                                     HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(pictureDeleteRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        pictureService.deletePicture(pictureDeleteRequest, userService.getLoginUser(httpServletRequest));
        return ResultUtils.success("删除成功");
    }

    /**
     * 图片修改请求
     *
     * @param pictureUpdateRequest 图片修改请求
     * @param httpServletRequest HTTP请求头信息
     * @return 修改成功
     */
    @Auth(value = {Authority.MANAGE,Authority.GENERAL})
    @PostMapping("/update")
    public Response<?> updatePicture(@RequestBody PictureUpdateRequest pictureUpdateRequest,
                                          HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(pictureUpdateRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        pictureService.updatePicture(pictureUpdateRequest, userService.getLoginUser(httpServletRequest));
        return ResultUtils.success("修改成功");
    }

    /**
     * id查询图片
     *
     * @param pictureId 图片id
     * @param httpServletRequest HTTP请求头信息
     * @return 图片封装信息
     */
    @Auth(value = {Authority.MANAGE,Authority.GENERAL})
    @GetMapping("/get")
    public Response<PictureVO> getPictureById(@RequestParam("id") long pictureId,
                                              HttpServletRequest httpServletRequest){
        Picture picture = pictureService.getPictureById(pictureId, userService.getLoginUser(httpServletRequest));
        return ResultUtils.success(pictureService.ObjToVO(picture));
    }

    /**
     * 分页查询(带缓存)
     *
     * @param picturePageQueryRequest 图片分页查询请求
     * @param httpServletRequest HTTP请求头信息
     * @return 分页图片封装信息
     */
    @Auth(value = {Authority.MANAGE,Authority.GENERAL})
    @PostMapping("/list/page")
    public Response<Page<PictureVO>> listPictureByPage(@RequestBody PicturePageQueryRequest picturePageQueryRequest,
                                                       HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(picturePageQueryRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        Page<Picture> picturePage;
        if (picturePageQueryRequest.getIsPublic().equals(false)){
            // 私人图库直接从数据库查
            picturePage = pictureService.listPictureByPage(picturePageQueryRequest, userService.getLoginUser(httpServletRequest));
        }else {
            // 公共图库优先从缓存查询
            picturePage = pictureService.listPictureByPageWithCache(picturePageQueryRequest, userService.getLoginUser(httpServletRequest));
        }
        // 去敏
        Page<PictureVO> pictureVOPage = new Page<PictureVO>(picturePage.getCurrent(), picturePage.getPages(), picturePage.getTotal())
                .setRecords(pictureService.ObjToVO(picturePage.getRecords()));
        return ResultUtils.success(pictureVOPage);
    }

    /**
     * 审核
     *
     * @param pictureReviewRequest 图片审核请求
     * @param httpServletRequest HTTP请求头信息
     * @return 审核成功
     */
    @Auth(value = Authority.MANAGE)
    @PostMapping("/review")
    public Response<?> reviewPicture(@RequestBody PictureReviewRequest pictureReviewRequest,
                                          HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(pictureReviewRequest == null, StatusCode.BAD_REQUEST, "参数错误");
        pictureService.reviewPicture(pictureReviewRequest, userService.getLoginUser(httpServletRequest));
        return ResultUtils.success("审核成功");
    }

    /**
     * 获取标签分类
     *
     * @return 标签分类
     */
    @GetMapping("/tag_category")
    public Response<PictureTagCategory> listPictureTagCategory() {
        PictureTagCategory pictureTagCategory = new PictureTagCategory();
        // 预设分类
        List<String> categories = Arrays.asList("美图","壁纸", "头像", "表情","现实");
        // 获取数据库标签库
        List<Tag> tags = tagService.listTag();
        List<String> tagStrings = new ArrayList<>();
        for (Tag tag: tags){
            tagStrings.add(tag.getTagName());
        }
        pictureTagCategory.setTags(tagStrings);
        pictureTagCategory.setCategories(categories);
        return ResultUtils.success(pictureTagCategory);
    }

    /**
     * 随机图片
     *
     * @return 随机图片
     */
    @GetMapping("/random")
    public Response<List<PictureVO>> randomPictures() {
        List<Picture> pictures = pictureService.randomPicturesWithCache(5);
        // 脱敏
        List<PictureVO> pictureVOS = pictureService.ObjToVO(pictures);
        return ResultUtils.success(pictureVOS);
    }

    /**
     * 清除图片缓存
     *
     * @return 清除成功
     */
    @Auth(value = Authority.MANAGE)
    @PostMapping("/clear-cache")
    public Response<?> clearPictureCache() {
        pictureService.clearPictureCache();
        return ResultUtils.success("清除成功");
    }
}
